package com.ljf.config.domain.base;

import com.ljf.common.exception.ServiceException;
import com.ljf.common.utils.CollectionUtil;
import com.ljf.common.utils.DateUtil;
import com.ljf.common.utils.StringUtil;
import com.ljf.config.enums.ConfigBaseImpulseSenderDetailTypeEnum;
import com.ljf.config.enums.ConfigBaseImpulseSenderDetailTypeSerialModeEnum;
import com.ljf.config.enums.ConfigBaseImpulseSenderHeaderRefreshModeEnum;
import com.ljf.config.vo.ConfigBaseImpulseSenderDetailVO;
import com.ljf.config.vo.ConfigBaseImpulseSenderHeaderVO;
import com.ljf.config.vo.ConfigDatImpulseSenderConditionVO;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 发号器配置表头  基础服务
 *
 * @author LJF
 * @since 2025-01-18
 */
@Component
public class ConfigBaseImpulseSenderHeaderBaseService {

    /**
     * 批量生成编码
     *
     * @param codeList
     * @param headerList
     * @param detailList
     * @param conditionList
     * @param generateFlag
     * @return
     * @throws ServiceException
     */
    public List<String> generateUniqueCodeList(List<String> codeList, List<ConfigBaseImpulseSenderHeaderVO> headerList, List<ConfigBaseImpulseSenderDetailVO> detailList, List<ConfigDatImpulseSenderConditionVO> conditionList, boolean generateFlag) throws ServiceException {
        if (CollectionUtil.isEmpty(codeList)) {
            return Collections.emptyList();
        }
        Map<String, ConfigBaseImpulseSenderHeaderVO> headerMap = headerList.stream().collect(
                Collectors.toMap(ConfigBaseImpulseSenderHeaderVO::getCode, Function.identity(), (a, b) -> a)
        );
        Map<String, List<ConfigBaseImpulseSenderDetailVO>> detailMap = detailList.stream().collect(
                Collectors.groupingBy(ConfigBaseImpulseSenderDetailVO::getCode, Collectors.toList())
        );
        Map<String, List<ConfigDatImpulseSenderConditionVO>> conditionMap = conditionList.stream().collect(
                Collectors.groupingBy(ConfigDatImpulseSenderConditionVO::getCode, Collectors.toList())
        );
        List<String> resultList = new ArrayList<>();
        for (String code : codeList) {
            resultList.add(this.generateUniqueCode(headerMap.get(code), detailMap.get(code), conditionMap.get(code), generateFlag));
        }
        return resultList;
    }

    /**
     * 生成编码
     *
     * @param header
     * @param detailList
     * @param conditionList
     * @param generateFlag
     * @return
     * @throws ServiceException
     */
    private String generateUniqueCode(ConfigBaseImpulseSenderHeaderVO header, List<ConfigBaseImpulseSenderDetailVO> detailList, List<ConfigDatImpulseSenderConditionVO> conditionList, boolean generateFlag) throws ServiceException {
        if (header == null || CollectionUtil.isEmpty(detailList)) {
            if (generateFlag) {
                throw new ServiceException("生成编码异常:配置信息不存在");
            }
            else {
                return "生成编码异常:配置信息不存在";
            }
        }
        if (conditionList == null) {
            if (generateFlag) {
                throw new ServiceException("生成编码异常:发号器未初始化");
            }
            else {
                return "生成编码异常:发号器未初始化";
            }
        }
        Date date = new Date();
        detailList.sort(Comparator.comparing(ConfigBaseImpulseSenderDetailVO::getSort));
        Map<Integer, ConfigDatImpulseSenderConditionVO> conditionMap = conditionList.stream()
                .collect(Collectors.toMap(ConfigDatImpulseSenderConditionVO::getSort, Function.identity(), (a, b) -> a));
        StringBuilder code = new StringBuilder();
        for (ConfigBaseImpulseSenderDetailVO detail : detailList) {
            if (Objects.equals(detail.getType(), ConfigBaseImpulseSenderDetailTypeEnum.FIXED_VALUE.getCode())) {
                code.append(detail.getValue());
            }
            else if (Objects.equals(detail.getType(), ConfigBaseImpulseSenderDetailTypeEnum.CHANGE_VALUE.getCode())) {
                code.append("{").append(detail.getValue()).append("}");
            }
            else if (Objects.equals(detail.getType(), ConfigBaseImpulseSenderDetailTypeEnum.CURRENT_DATE.getCode())) {
                code.append(DateUtil.formatCommonDate(date, detail.getValue()));
            }
            else if (Objects.equals(detail.getType(), ConfigBaseImpulseSenderDetailTypeEnum.SERIAL_NUMBER.getCode())) {
                if (!conditionMap.containsKey(detail.getSort())) {
                    if (generateFlag) {
                        throw new ServiceException("生成编码异常:发号器未初始化");
                    }
                    else {
                        return "生成编码异常:发号器未初始化";
                    }
                }
                ConfigDatImpulseSenderConditionVO condition = conditionMap.get(detail.getSort());
                Date oldDate = condition.getRecordDate();
                boolean refreshNum = false;
                if (Objects.equals(ConfigBaseImpulseSenderHeaderRefreshModeEnum.YEAR.getCode(), header.getRefreshMode())) {
                    if (!StringUtil.equals(DateUtil.formatYear(oldDate), DateUtil.formatYear(date))) {
                        refreshNum = true;
                    }
                }
                else if (Objects.equals(ConfigBaseImpulseSenderHeaderRefreshModeEnum.MONTH.getCode(), header.getRefreshMode())) {
                    if (!StringUtil.equals(DateUtil.formatYearMonth(oldDate), DateUtil.formatYearMonth(date))) {
                        refreshNum = true;
                    }
                }
                else if (Objects.equals(ConfigBaseImpulseSenderHeaderRefreshModeEnum.DAY.getCode(), header.getRefreshMode())) {
                    if (!StringUtil.equals(DateUtil.formatYearMonthDay(oldDate), DateUtil.formatYearMonthDay(date))) {
                        refreshNum = true;
                    }
                }
                else if(!Objects.equals(ConfigBaseImpulseSenderHeaderRefreshModeEnum.NOT_REFRESH.getCode(), header.getRefreshMode())) {
                    if (generateFlag) {
                        throw new ServiceException("配置信息异常:刷新模式");
                    }
                    else {
                        return "配置信息异常:刷新模式";
                    }
                }
                condition.setRecordDate(date);
                if (refreshNum) {
                    condition.setCurrentValue("1");
                }
                else {
                    condition.setCurrentValue(String.valueOf(Long.parseLong(condition.getCurrentValue()) + 1L));
                }
                String value = detail.getValue();
                if (!value.contains("-")) {
                    if (Objects.equals(ConfigBaseImpulseSenderDetailTypeSerialModeEnum.NOT_FILLED.getCode(), Integer.parseInt(value))) {
                        code.append(value);
                    }
                    else {
                        if (generateFlag) {
                            throw new ServiceException("配置信息异常:不存在对应的流水号类型");
                        }
                        else {
                            return "配置信息异常:不存在对应的流水号类型";
                        }
                    }
                }
                else {
                    Integer serialMode = Integer.parseInt(value.substring(0, value.indexOf("-")));
                    value = value.substring(value.indexOf("-") + 1);
                    int num = Integer.parseInt(value.substring(value.indexOf("-") + 1));
                    int fillCount = num - condition.getCurrentValue().length();
                    StringBuilder fillValue = new StringBuilder();
                    for (int i = 0; i < fillCount; i++) {
                        fillValue.append(value, 0, value.indexOf("-"));
                    }
                    if (Objects.equals(ConfigBaseImpulseSenderDetailTypeSerialModeEnum.FILL_LEFT.getCode(), serialMode)) {
                        code.append(fillValue).append(condition.getCurrentValue());
                    }
                    else if (Objects.equals(ConfigBaseImpulseSenderDetailTypeSerialModeEnum.RIGHT_FILL.getCode(), serialMode)) {
                        code.append(condition.getCurrentValue()).append(fillValue);
                    }
                    else {
                        if (generateFlag) {
                            throw new ServiceException("配置信息异常:不存在对应的流水号类型");
                        }
                        else {
                            return "配置信息异常:不存在对应的流水号类型";
                        }
                    }
                }
            }
            else {
                if (generateFlag) {
                    throw new ServiceException("配置信息异常:明细类型");
                }
                else {
                    return "配置信息异常:明细类型";
                }
            }
        }
        return code.toString();
    }

}
